package com.naiterui.ehp.bs.patient.dao.impl;

import com.naiterui.common.repository.page.JpaPageConvertor;
import com.naiterui.common.repository.page.Page;
import com.naiterui.common.repository.page.PageVO;
import com.naiterui.ehp.bp.domain.*;
import com.naiterui.ehp.bp.utils.lang.StringUtil;
import com.naiterui.ehp.bs.patient.dao.IDoctorDao;
import com.naiterui.ehp.bs.patient.repository.*;
import com.naiterui.ehp.bs.patient.vo.doctor.DoctorVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

import java.math.BigInteger;
import java.util.*;

/**
 * 医生信息持久化实现
 *
 * @version 2015年6月21日 上午11:56:55 by Amber
 * @see IDoctorDao、DefaultBaseDaoImpl
 */
@Component
public class ApDoctorDaoImpl implements IDoctorDao {

    @Autowired
    private IApDoctorRepository doctorRepository;
    @Autowired
    private IApPatientPersonDoctorRepository patientPersonDoctorRepository;
    @Autowired
    private IApDrConsultRepository drConsultRepository;
    @Autowired
    private IApDrBayConsultRepository drBayConsultRepository;
    @Autowired
    private IApHospitalRepository hospitalRepository;

    /**
     * 根据患者id查询患者的所有私人医生列表ids
     *
     * @param patientId
     * @param accountStatus 账户状态0:正常，1:禁用
     *
     * @return
     *
     * @Author linhf
     * @Date 2016年4月14日
     * @since 1.0.0
     */
    @Override
    public Map<String, Object> getMyPrivateDoctor(Long patientId, int page, int num, Integer accountStatus) {
        Map<String, Object> map = new HashMap<>();
        Long totalCount = doctorRepository.countPrivateDoctorNum(patientId, accountStatus);
        List<Object[]> list = doctorRepository.findPatientPersonalList(patientId, accountStatus);
        // 如果page和num都大于0时说明需要分页查询，否则查询全部记录
        if (page > 0 && num > 0) {
            list = doctorRepository.findPatientPersonalList(patientId, accountStatus, (page - 1) * num, num);
        }
        map.put("totalCount", totalCount);
        map.put("list", list);

        return map;
    }

    @Override
    public PageVO<DoctorVO> getMyDoctors(Long patientId, Pageable pageable) {
        org.springframework.data.domain.Page<DoctorVO> result = doctorRepository.findByPatientIdPage(patientId, pageable);
        return JpaPageConvertor.pageConvert(result);
    }

    @Override
    public PageVO<DoctorVO> getAllDoctors(Pageable pageable) {
        org.springframework.data.domain.Page<DoctorVO> result = doctorRepository.findAllPage(pageable);
        return JpaPageConvertor.pageConvert(result);
    }

    @Override
    public int getFansNum(Long doctorId) {
        // 查询关注人数
        Integer fansResult = doctorRepository.countAttendNum(doctorId);

        int fansNum = 0;

        if (null != fansResult) {
            fansNum = fansResult;
        }

        // 查询绑定人数
        Integer personalResult = doctorRepository.countPersonalNum(doctorId);

        int personalNum = 0;

        if (null != personalResult) {
            personalNum = personalResult;
        }
        return personalNum + fansNum;
    }

    // TODO 经前端查询此接口未在使用，后期遇到使用指出再做切换JPA操作
    @Override
    public Page<Object[]> findDoctors(String keyword, Integer departmentId, Integer cityId, int page, int num) {

        /*// 拼接in查询条件
        StringBuilder citys = null; // 关键字，城市名匹配 or
        StringBuilder hospitals = null; // 关键字，医院名匹配 or
        StringBuilder departments = null; // 科室过滤 and
        StringBuilder citySelect = null; // 城市过滤 and

        String hql = "select d.id,d.name,d.head_url,d.title_id,d.department_id,d.hospital_id,d.hospital_name,d.expertise,praise.num,d.status,d" +
                ".custom_department from (select * from doctor where account_status = 0 and status = 1 and type=0";// 已认证且未被禁用的用户,
        // 非测试医生（type＝0为普通医生，1为测试医生）

        // and 拼接一级科室过滤
        if (departmentId != null && departmentId > 0) {
            String depSql = "select id from dr_department where id= ? or parent_id = ?";// 当前科室以及所有子科室
            List departs = super.findBySQLQuery(depSql, departmentId, departmentId);
            if (departs.size() > 0) {
                departments = new StringBuilder("(");
                for (Iterator iter = departs.iterator(); iter.hasNext(); ) {
                    departments.append(iter.next());
                    if (iter.hasNext()) {
                        departments.append(",");
                    }
                }
                departments.append(")");
            }
        }
        if (departments != null) {
            hql += " and department_id in" + departments;
        }

        // and 拼接城市过滤
        if (cityId != null && cityId > 0) {
            String csql = "select id from cms_city where id = ? or parent_id = ?"; // 当前城市以及所有子城市
            List cids = super.findBySQLQuery(csql, cityId, cityId);
            if (cids.size() > 0) {
                citySelect = new StringBuilder("(");
                for (Iterator iter = cids.iterator(); iter.hasNext(); ) {
                    citySelect.append(iter.next());
                    if (iter.hasNext()) {
                        citySelect.append(",");
                    }
                }
                citySelect.append(")");
            }
        }
        if (citySelect != null) {
            hql += " and city_id in" + citySelect;
        }

        // and 拼接关键字

        if (StringUtils.isNotEmpty(keyword)) {

            // 关键字 or 匹配城市
            String citySql = "select id from cms_city where name like ?";
            List cids = super.findBySQLQuery(citySql, "%" + keyword + "%");

            if (cids.size() > 0) {

                citys = new StringBuilder("(");
                for (Iterator iter = cids.iterator(); iter.hasNext(); ) {
                    citys.append(iter.next());
                    if (iter.hasNext()) {
                        citys.append(",");
                    }
                }
                citys.append(")");

            }

            // 关键字 or 匹配医院
            String hpSql = "select id from dr_hospital where name like ?";
            List hpIds = super.findBySQLQuery(hpSql, "%" + keyword + "%");

            if (hpIds.size() > 0) {
                hospitals = new StringBuilder("(");
                for (Iterator iter = hpIds.iterator(); iter.hasNext(); ) {
                    hospitals.append(iter.next());
                    if (iter.hasNext()) {
                        hospitals.append(",");
                    }
                }
                hospitals.append(")");
            }
        }

        if (citys == null && hospitals == null) {
            hql += " and (name like ? or hospital_name like ?)";
        } else {
            hql += " and ( name like ? or hospital_name like ?";
            if (citys != null) {
                hql += " or city_id in " + citys;
            }
            if (hospitals != null) {
                hql += " or hospital_id in " + hospitals;
            }
            hql += ")";
        }

        hql += ") d left join (select  count(id) as num,doctor_id as did from dr_comment where result=1 group by doctor_id) praise on praise.did=d" +
                ".id  order by praise.num desc;";
        // Page<Doctor> result = super.pagedQuery(hql, page, num, "%" + keyword
        // + "%");
        List<Object[]> results = super.findBySQLQuery(hql, "%" + keyword + "%", "%" + keyword + "%");
        Page<Object[]> pageResult = new Page<>();
        pageResult.setPageNo(page);
        pageResult.setPageSize(num);
        int totalCount = results.size();
        pageResult.setTotalCount(totalCount);
        if (results.size() > 0) {
            int start = Page.getStartOfPage(page, num);
            int end = start + num;
            if (start > results.size()) {
                // 页码信息有误，返回首页数据
                start = 0;
                end = start + num;
            }
            pageResult.setResult(results.subList(start, end > results.size() ? results.size() : end));
        }
        return pageResult;*/
        return null;
    }

    @Override
    public String getHospitalName(Integer hospitalId) {
        List<String> result = doctorRepository.getHospitalName(hospitalId);
        return result.size() > 0 ? result.get(0) : "";
    }

    @Override
    public List<DrConsult> getDoctorConsults(Long doctorId) {
        return drConsultRepository.findByDoctorIdOrderByWeekIndex(doctorId);
    }

    @Override
    public List<DrBayConsult> getDoctorBayConsults(Long doctorId) {
        return drBayConsultRepository.findByDoctorIdOrderByWeekIndex(doctorId);
    }

    @Override
    public List<Doctor> getPersonalDoctors(Long patientId, int accountStatus) {
        List<Doctor> result = new ArrayList<>();

        result = doctorRepository.getPersonalDoctor(patientId);

        // 状态值为-1，取全部状态数据，否则按状态取
        if (accountStatus != -1) {
            // 加状态过滤
            result = doctorRepository.getPersonalDoctor(patientId, accountStatus);
        }
        return result;
    }

    @Override
    public Hospital getDoctorHospital(Integer hospitalId) {
        return hospitalRepository.get(hospitalId);
    }

    @Override
    public Doctor getNewPersonalDoctor(Long patientId) {
        List<PatientPersonDoctor> personalDoctors = patientPersonDoctorRepository.findByPersonPKPatientIdOrderByCreateAtDesc(patientId);
        if (personalDoctors.size() > 0) {
            Long doctorId = personalDoctors.get(0).getPersonPK().getDoctorId();
            return doctorRepository.get(doctorId);
        } else {
            return null;
        }
    }

    @Override
    public Map<Long, Doctor> getDoctorInfoByDrIds(Set<Long> doctorIds) {
        Map<Long, Doctor> doctorMap = new HashMap<>();
        // 参数为空直接返回
        if (doctorIds == null || doctorIds.size() == 0) {
            return doctorMap;
        }

        List<Doctor> doctors = doctorRepository.findByIdIn(doctorIds);

        // 处理查询结果
        for (Doctor doctor : doctors) {
            doctorMap.put(doctor.getId(), doctor);
        }
        return doctorMap;
    }

    @Override
    public Integer getPatientNum(Long doctorId) {
        // 查询医生下面的患者数
        Integer patientNum = doctorRepository.countPersonalPatients(doctorId);
        return patientNum;
    }

    @Override
    public Map<String, Integer> getDoctorCommentNum(Long doctorId) {
        // 所有评价数
        Integer countALL = doctorRepository.countConsultComment(doctorId);

        // 好评数
        Integer countGood = doctorRepository.countConsultCommentLevel(doctorId);
        Map<String, Integer> commentMap = new HashMap<>();
        commentMap.put("all", countALL);
        commentMap.put("good", countGood);
        return commentMap;
    }

    /**
     * @param doctorIds
     *
     * @return
     *
     * @Author Gaoll
     * @Date 2016年8月12日
     * @since 1.0.0
     */
    @Override
    public Map<Long, Doctor> getDoctorMap(Collection<Long> doctorIds) {
        Map<Long, Doctor> resultMap = new HashMap<>();
        String queryStr = StringUtil.convertCollection(doctorIds);
        if (StringUtils.isNotEmpty(queryStr)) {
            List<Doctor> doctorList = doctorRepository.findByIdIn(doctorIds);
            if (null != doctorList && !doctorList.isEmpty()) {
                for (Doctor tempDoctor : doctorList) {
                    resultMap.put(tempDoctor.getId(), tempDoctor);
                }
            }
        }
        return resultMap;
    }

    @Override
    public List<Doctor> getDoctorByIds(List<Long> doctorIds) {
        return doctorRepository.findByIdInAndAccountStatus(doctorIds, 0);
    }

    @Override
    public Map<Long, Integer> getDoctorPatientNumByIds(List<Long> ids) {
        Map<Long, Integer> map = new HashMap<>();
        String queryStr = StringUtil.convertCollection(ids);
        if (StringUtils.isNotEmpty(queryStr)) {
            List<Object[]> countList = doctorRepository.getDoctorPatientNumByIds(queryStr);
            if (countList != null && !countList.isEmpty()) {
                for (Object[] column : countList) {
                    Long doctorId = ((BigInteger) column[0]).longValue();
                    Integer count = ((BigInteger) column[1]).intValue();
                    map.put(doctorId, count);
                }
            }
        }
        //处理无服务患者数的数据
        ids.forEach(s -> map.putIfAbsent(s, 0));
        return map;
    }

    @Override
    public Map<Long, Map<String, Integer>> getDoctorCommentNumByIds(List<Long> ids) {
        Map<Long, Map<String, Integer>> doctorMap = new HashMap<>();
        Map<Long, Integer> allMap = new HashMap<>();
        Map<Long, Integer> goodMap = new HashMap<>();
        String queryStr = StringUtil.convertCollection(ids);
        if (StringUtils.isNotEmpty(queryStr)) {
            // 总评价数
            List<Object[]> countList = doctorRepository.getDoctorCommentNumByIds(queryStr);
            if (countList != null && !countList.isEmpty()) {
                for (Object[] column : countList) {
                    Long doctorId = ((BigInteger) column[0]).longValue();
                    Integer count = ((BigInteger) column[1]).intValue();
                    allMap.put(doctorId, count);
                }
            }
            // 好评数
            List<Object[]> goodList = doctorRepository.getDoctorCommentNumByIdsLevel(queryStr);
            if (goodList != null && !goodList.isEmpty()) {
                for (Object[] column : goodList) {
                    Long doctorId = ((BigInteger) column[0]).longValue();
                    Integer count = ((BigInteger) column[1]).intValue();
                    goodMap.put(doctorId, count);
                }
            }
            // 整合数据
            for (Long id : ids) {
                Map<String, Integer> allGoodMap = new HashMap<>();
                if (allMap.get(id) == null) {
                    allGoodMap.put("all", 0);
                } else {
                    allGoodMap.put("all", allMap.get(id));
                }

                if (goodMap.get(id) == null) {
                    allGoodMap.put("good", 0);
                } else {
                    allGoodMap.put("good", goodMap.get(id));
                }
                doctorMap.put(id, allGoodMap);
            }
        }
        return doctorMap;
    }

    @Override
    public List<DoctorVO> getMyDoctorList(Long patientId, Integer accountStatus) {
        return doctorRepository.getMyDoctorList(patientId, accountStatus);
    }

    @Override
    public Doctor get(Long id) {
        return doctorRepository.get(id);
    }
}
